package org.study.javafx.study01.calculator.code;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Administrator
 */
@Slf4j
public class CalculatorCode extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    // 定义变量，用于存储数值和操作符
    private double num1 = 0;
    private double num2 = 0;
    /**
     * 运算符
     */
    private String operator = "";
    /**
     * 小数点
     */
    private boolean decimal = false;
    private boolean newCalculation = true;

    @Override
    public void init() throws Exception {
        super.init();
    }

    @Override
    public void start(Stage primaryStage) {
        // 设置窗口标题
        primaryStage.setTitle("Calculator");
        // 创建一个网格面板，并进行布局
        GridPane grid = new GridPane();
        grid.setAlignment(Pos.CENTER);// 位置居中
        // 设置水平和垂直间距为 10
        grid.setHgap(10);
        grid.setVgap(10);
        // 设置网格面板的填充为 30（可以删除）
        grid.setPadding(new Insets(30, 30, 30, 30));
        // 创建一个文本框，用于显示计算结果
        TextField display = new TextField();
        // 结果是显示栏不可编辑
        display.setEditable(false);

        // 设置文本框的水平对齐方式为右对齐，并将其宽度设置为 200
        display.setAlignment(Pos.CENTER_RIGHT);
        display.setPrefWidth(200);
        // 将文本框添加到网格面板中，占据第 0 列、第 0 行，跨度为 4 行和 1 列
        grid.add(display, 0, 0, 4, 1);

        // 创建按钮1
        Button btn1 = new Button("1");
        // 将数字按钮1添加到网格面板中
        btn1.setOnAction(event -> handleNumberButton("1", display));
        // 位置占0列1行
        grid.add(btn1, 0, 1);

        Button btn2 = new Button("2");
        btn2.setOnAction(event -> handleNumberButton("2", display));
        grid.add(btn2, 1, 1);

        Button btn3 = new Button("3");
        btn3.setOnAction(event -> handleNumberButton("3", display));
        grid.add(btn3, 2, 1);

        Button btn4 = new Button("4");
        btn4.setOnAction(event -> handleNumberButton("4", display));
        grid.add(btn4, 0, 2);

        Button btn5 = new Button("5");
        btn5.setOnAction(event -> handleNumberButton("5", display));
        grid.add(btn5, 1, 2);

        Button btn6 = new Button("6");
        btn6.setOnAction(event -> handleNumberButton("6", display));
        grid.add(btn6, 2, 2);

        Button btn7 = new Button("7");
        btn7.setOnAction(event -> handleNumberButton("7", display));
        grid.add(btn7, 0, 3);

        Button btn8 = new Button("8");
        btn8.setOnAction(event -> handleNumberButton("8", display));
        grid.add(btn8, 1, 3);

        Button btn9 = new Button("9");
        btn9.setOnAction(event -> handleNumberButton("9", display));
        grid.add(btn9, 2, 3);

        Button btn0 = new Button("0");
        btn0.setOnAction(event -> handleNumberButton("0", display));
        grid.add(btn0, 1, 4);

        Button btnDecimal = new Button(".");
        btnDecimal.setOnAction(event -> handleDecimalButton(display));
        grid.add(btnDecimal, 2, 4);

        // 创建运算符按钮，并将其添加到网格面板中
        Button btnAdd = new Button("+");
        btnAdd.setOnAction(event -> handleOperatorButton("+", display));
        grid.add(btnAdd, 3, 1);

        Button btnSubtract = new Button("-");
        btnSubtract.setOnAction(event -> handleOperatorButton("-", display));
        grid.add(btnSubtract, 3, 2);

        Button btnMultiply = new Button("*");
        btnMultiply.setOnAction(event -> handleOperatorButton("*", display));
        grid.add(btnMultiply, 3, 3);

        Button btnDivide = new Button("/");
        btnDivide.setOnAction(event -> handleOperatorButton("/", display));
        grid.add(btnDivide, 3, 4);

        Button btnClear = new Button("C");
        btnClear.setOnAction(event -> handleClearButton(display));
        grid.add(btnClear, 0, 4);

        Button btnSign = new Button("+/-");
        btnSign.setOnAction(event -> handleSignButton(display));
        grid.add(btnSign, 0, 5);

        Button btnPercent = new Button("%");
        btnPercent.setOnAction(event -> handlePercentButton(display));
        grid.add(btnPercent, 1, 5);

        Button btnEquals = new Button("=");
        btnEquals.setOnAction(e -> handleEqualsButton(display));
        grid.add(btnEquals, 3, 5);

        // 创建一个场景，并将网格面板添加到其中
        Scene scene = new Scene(grid, 240, 250);
        primaryStage.setScene(scene);

        // 监听键盘事件
        scene.setOnKeyPressed(event -> {
            KeyCode keyCode = event.getCode();
            if (keyCode.isDigitKey()) {
                handleNumberButton(keyCode.getName(), display);
            } else if (keyCode == KeyCode.ADD || keyCode == KeyCode.PLUS) {
                handleOperatorButton("+", display);
            } else if (keyCode == KeyCode.SUBTRACT || keyCode == KeyCode.MINUS) {
                handleOperatorButton("-", display);
            } else if (keyCode == KeyCode.MULTIPLY) {
                handleOperatorButton("*", display);
            } else if (keyCode == KeyCode.DIVIDE) {
                handleOperatorButton("/", display);
            } else if (keyCode == KeyCode.PERIOD) {
                handleDecimalButton(display);
            } else if (keyCode == KeyCode.ENTER) {
                handleEqualsButton(display);
            }
        });

        // 显示窗口
        primaryStage.show();
    }

    @Override
    public void stop() throws Exception {
        super.stop();
    }

    /**
     * 处理数字按钮的事件
     *
     * @param number  按下的数字
     * @param display 显示结果的文本框
     */
    private void handleNumberButton(String number, TextField display) {
        if (newCalculation) {
            // 清除文本框
            display.clear();
            newCalculation = false;
        }
        String text = display.getText();
        if ("0".equals(text)) {
            display.setText(number);
        } else if (!decimal || !text.contains(".")) {
            display.setText(text + number);
        }
    }

    /**
     * 处理运算符按钮的事件
     *
     * @param operator 按下的运算符号
     * @param display  显示结果的文本框
     */
    private void handleOperatorButton(String operator, TextField display) {
        if (!this.operator.isEmpty()) {
            // 判断当前计算器是否已经有运算符被按下，如果有，则调用 handleEqualsButton 方法进行计算
            handleEqualsButton(display);
        }
        num1 = Double.parseDouble(display.getText());
        this.operator = operator;
        display.setText(num1 + " " + operator + " ");
        decimal = false;
        newCalculation = false;
    }

    /**
     * 处理小数点按钮的事件
     *
     * @param display 显示结果的文本框
     */
    private void handleDecimalButton(TextField display) {
        if (!decimal) {
            String text = display.getText();
            if (newCalculation) {
                display.clear();
                newCalculation = false;
            }
            display.setText(text + ".");
            decimal = true;
        }
    }

    /**
     * 处理清除按钮的事件
     *
     * @param display 显示结果的文本框
     */
    private void handleClearButton(TextField display) {
        display.clear();
        num1 = 0;
        num2 = 0;
        operator = "";
        decimal = false;
        newCalculation = true;
    }

    /**
     * 处理正负号按钮的事件
     *
     * @param display 显示结果的文本框
     */
    private void handleSignButton(TextField display) {
        // 获取文本框中的数字或运算符
        String text = display.getText();
        if (!"".equals(text) && !"0".equals(text)) {
            if (text.startsWith("-")) {
                display.setText(text.substring(1));
            } else {
                display.setText("-" + text);
            }
        }
    }

    /**
     * 处理百分号按钮的事件
     *
     * @param display 显示结果的文本框
     */
    private void handlePercentButton(TextField display) {
        double num = Double.parseDouble(display.getText());
        display.setText(Double.toString(num / 100));
        newCalculation = true;
    }

    /**
     * 处理等于按钮的事件
     *
     * @param display 显示结果的文本框
     */
    private void handleEqualsButton(TextField display) {
        if (!"".equals(operator)) {
            String text = display.getText();
            int index = text.indexOf(operator);
            num2 = Double.parseDouble(text.substring(index + operator.length()));
            switch (operator) {
                case "+":
                    num1 += num2;
                    break;
                case "-":
                    num1 -= num2;
                    break;
                case "*":
                    num1 *= num2;
                    break;
                case "/":
                    if (num2 == 0) {
                        display.setText("除零错误");
                        num1 = 0;
                        num2 = 0;
                        operator = "";
                        decimal = false;
                        newCalculation = true;
                        return;
                    }
                    num1 /= num2;
                    break;
            }
            // 重置计算器为起始状态
            // 输入框没有字符则为第一个操作数
            display.setText(Double.toString(num1));
            // 无操作数
            operator = "";
            // 没有输入小数点
            decimal = false;
            // 开始新的一次计算
            newCalculation = true;
        }
    }
}
